
'use strict';

const APP_PATTERN = /(MicroMessenger|QQ|__weibo__|Feifan|education)\/?([\d\.]+)/i;

const APP_NAME_DICT = {
    MicroMessenger: 'Weixin',
    __weibo__: 'Weibo',
};
const BROWSER_PATTERN = /(UCWEB|UCBrowser|MQQBrowser|MiuiBrowser|Chrome|CriOS)[\s\/]([\d\.]+)/i;
const BROWSER_NAME_DICT = {
    UCWEB: 'UC',
    UCBrowser: 'UC',
    MQQBrowser: 'QQ',
    MiuiBrowser: 'Xiaomi',
    CriOS: 'Chrome',
};

const OS_NAME_PATTERN = /(Android|iPhone|iPad|iPod)/i;
const OS_VERSION_PATTERN = /Android[\s\/]([\d\.]+)|OS ([\d_\.]+) like Mac OS X/i;
const HYBRID_PATTERN = /hybrid[\s\/]([\d\.]+)/i;
const VERSION_PATTERN = /^\d+(\.\d+)*$/;

export let UA = window.navigator.userAgent;

export let _setUserAgent = (userAgent) => {
    UA = userAgent;
};

export let getAppName = () => {
    let matched = UA.match(APP_PATTERN);
    if (matched === null) {
        return 'unknown';
    }
    return APP_NAME_DICT[matched[1]] ? APP_NAME_DICT[matched[1]] : matched[1];
};

export let getOSName = () => {
    let matched = UA.match(OS_NAME_PATTERN);
    return matched ? matched[1] : 'unknow';
};

export let isIOS = () => {
    let osName = getOSName();
    return osName === 'iPhone' || osName === 'iPod' || osName === 'iPad';
};

export let getBrowserName = () => {
    let matched = UA.match(BROWSER_PATTERN);
    if (matched === null) {
        if (isIOS()) {
            if (/Safari/.test(UA)) {
                return 'Safari';
            }
            return 'iOS Webview';
        }
        return 'unknow';
    }
    return BROWSER_NAME_DICT[matched[1]] ? BROWSER_NAME_DICT[matched[1]] : matched[1];
};

export let getAppVersion = () => {
    let matched = UA.match(APP_PATTERN);
    let version = matched ? matched[2] : '0.0.0';
    return version.replace(/_/g, '.');
};

export let getOSVersion = () => {
    let matched = UA.match(OS_VERSION_PATTERN);
    let version = matched ? (matched[1] || matched[2]) : '0.0.0';
    return version.replace(/_/g, '.');
};

export let getBrowserVersion = () => {
    let matched = UA.match(BROWSER_PATTERN);
    let version;
    if (matched === null) {
        if (isIOS()) {
            let versionMatched;
            if (/Safari/.test(UA)) {
                versionMatched = UA.match(/Version\/([\d\.]+)/);
            } else {
                versionMatched = UA.match(/OS ([\d_\.]+) like Mac OS X/);
            }
            version = versionMatched ? versionMatched[1] : '0.0.0';
        } else {
            version = '0.0.0';
        }
    } else {
        version = matched[2];
    }
    return version.replace(/_/g, '.');
};

// app
export let isWeixin = () => {
    let result = getAppName() === 'Weixin';
    return result;
};

export let isQQ = () => {
    let result = getAppName() === 'QQ';
    return result;
};

export let isWeibo = () => {
    let result = getAppName() === 'Weibo';
    return result;
};

export let isEducation = () => {
    let result = getAppName() === 'education';
    return result;
};

// os
export let isAndroid = () => {
    let result = getOSName() === 'Android';
    return result;
};

export let isIPhone = () => {
    let osName = getOSName();
    return osName === 'iPhone' || osName === 'iPod';
};

export let isIPad = () => {
    let result = getOSName() === 'iPad';
    return result;
};

// browser
export let isUC = () => {
    let result = false;
    if (UA.match(/(?:UCWEB|UCBrowser\/)([\d\.]+)/)) {
        result = true;
    }
    return result;
};

export let isXiaomi = () => {
    let result = false;
    if (UA.match(/MiuiBrowser\/([\d\.]+)/)) {
        result = true;
    }
    return result;
};

export let isChrome = () => {
    let result = getBrowserName() === 'Chrome';
    return result;
};

export let isSafari = () => {
    let result = getBrowserName() === 'Safari';
    return result;
};

export let isWebview = () => {
    let result = getBrowserName() === 'iOS Webview';
    return result;
};

// hybrid
export let isHybridExist = () => {
    let result = !!UA.match(HYBRID_PATTERN);
    return result;
};

export let getHybridVersion = () => {
    let matched = UA.match(HYBRID_PATTERN);
    return matched ? matched[1] : '0.0.0';
};

// versionCompare
let _isVersion = (v) => {
    let result = VERSION_PATTERN.test(v);
    return result;
};

export let compare = (v1, v2) => {
    if (_isVersion(v1) && _isVersion(v2)) {
        v1 = v1.toString().split('.');
        v2 = v2.toString().split('.');
        for (let i = 0, l1 = v1.length, l2 = v2.length; i < l1 || i < l2; i++) {
            let n1 = parseInt(v1[i], 10);
            let n2 = parseInt(v2[i], 10);
            // if (isNaN(n1)) {
            //     n1 = 0;
            // }
            // if (isNaN(n2)) {
            //     n2 = 0;
            // }
            if (n1 < n2) {
                return -1;
            } else if (n1 > n2) {
                return 1;
            }
        }
        return 0;
    }
    return console.error('version value is invalid');
};

export let version = (v) => {
    const funcObj = {
        gt(compareV) {
            return compare(v, compareV) > 0;
        },
        gte(compareV) {
            return compare(v, compareV) >= 0;
        },
        eq(compareV) {
            return compare(v, compareV) === 0;
        },
        lte(compareV) {
            return compare(v, compareV) <= 0;
        },
        lt(compareV) {
            return compare(v, compareV) < 0;
        },
    };
    return funcObj;
};

export const app = {
    getAppName,
    getAppVersion,
    isWeixin,
    isWeibo,
    isQQ,
    isEducation,
    isBeidian,
};

export const os = {
    isAndroid,
    isIPhone,
    isIPad,
    isIOS,
    getOSName,
    getOSVersion,
};

export const browser = {
    isUC,
    isXiaomi,
    isChrome,
    isSafari,
    isWebview,
    getBrowserName,
    getBrowserVersion,
};
export const hybrid = {
    isHybridExist,
    getHybridVersion,
};
export default {
    app,
    os,
    browser,
    hybrid,
    version,
};
